home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / tde210.zip / INT24.ASM < prev    next >
Assembly Source File  |  1992-11-13  |  11KB  |  268 lines

  1. ; Do a simple critical error handler (CEH).  It is designed to be memory model
  2. ; independent.  When we first install this CEH, pass in the FAR address of
  3. ; a CEH structure.  Save the address of CEH structure in the code segment of
  4. ; our assembly CEH replacement.  When a critical error occurs, load in the
  5. ; address of our CEH structure and save the return codes in the structure.
  6. ; Call the prompt functions in criterr.c, then return from interrupt.
  7. ;
  8. ; Let's set the error flag only if a Fail or Ignore condition is input by
  9. ; the user.  The Ignore option is not explicity supported by this algorithm,
  10. ; but it is returned for DOS versions less than 3.0.  The Fail option is
  11. ; not available for DOS versions less than 3.0.  If the user selects the
  12. ; Retry option, set the ceh.flag to OK, because there is no error.  By
  13. ; selecting Retry, the user just wants to retry the DOS operation, which is
  14. ; not necessarily an error condition.
  15. ;
  16. ; See:
  17. ;
  18. ;   Programmer's Reference Manual, Microsoft Corporation, Redmond,
  19. ;     Washington, 1986, Document No. 410630014-320-003-1285, pp. 1-20 thru
  20. ;     1-21, pp. 1-34 thru 1-38, p 1-99, pp. 1-121 thru 1-124, pp. 1-216 thru
  21. ;     1-218, pp. 2-1 thru 2-30.
  22. ;
  23. ;   Ray Duncan, _Advanced MS-DOS_, Microsoft Press, Redmond, Washington,
  24. ;     1986, ISBN 0-914845-77-2, pp 89-97, pp 130-133.
  25. ;
  26. ;
  27. ; Assembler flags:
  28. ;
  29. ;      QuickAssembler:   qcl /c int24.asm
  30. ;            MASM 6.0:   ml /c /Cp /Zm int24.asm
  31. ;
  32. ; Editor name:   TDE, the Thomson-Davis Editor.
  33. ; Author:        Frank Davis
  34. ; Date:          June 5, 1991, version 1.0
  35. ; Date:          July 29, 1991, version 1.1
  36. ; Date:          October 5, 1991, version 1.2
  37. ; Date:          January 20, 1992, version 1.3
  38. ; Date:          February 17, 1992, version 1.4
  39. ; Date:          April 1, 1992, version 1.5
  40. ; Date:          June 5, 1992, version 2.0
  41. ; Date:          October 31, 1992, version 2.1
  42. ;
  43. ; This code is released into the public domain, Frank Davis.  You may
  44. ; distribute it freely.
  45.  
  46. ;typedef struct {         typedef from tdestr.h
  47. ;   int  flag;
  48. ;   int  ecode;
  49. ;   int  rw;
  50. ;   int  drive;
  51. ;   int  extended;
  52. ;   int  class;
  53. ;   int  action;
  54. ;   int  locus;
  55. ;   int  dattr;
  56. ;   char dname[10];
  57. ;} CEH;
  58.  
  59. flag            EQU     0
  60. ecode           EQU     2
  61. rw              EQU     4
  62. drive           EQU     6
  63. extended        EQU     8
  64. class           EQU     10
  65. action          EQU     12
  66. locus           EQU     14
  67. dattr           EQU     16
  68. dname           EQU     18
  69.  
  70. ; see any DOS tech ref manaul for the format of device headers.
  71. ;
  72. dev_attr_word   EQU     4
  73. char_dev_name   EQU     10
  74.  
  75. ;
  76. ; external C routine in criterr.c
  77. ;
  78.         EXTRN   _crit_err_handler:FAR
  79.  
  80.  
  81. _TEXT   SEGMENT WORD PUBLIC 'CODE'
  82.         ASSUME  cs:_TEXT, ds:NOTHING, es:NOTHING
  83.         public  _install_ceh
  84.  
  85.  
  86. ;
  87. ; Prototype this function as far in the C header file so it may be used easily
  88. ; with any memory model.  See the last section in tdefunc.h for more info.
  89. ;
  90. _install_ceh    PROC    FAR
  91.         jmp     initialize
  92.  
  93. ceh_pointer     DW      ?,?     ; pointer to critical error handler structure
  94. dos_version     DW      ?       ; what version of DOS are we working with?
  95.  
  96. start:
  97. ;
  98. ;  the first thing we need to do is turn interrupts back on.  interrupts
  99. ;  are disabled when the handler receives control.
  100. ;
  101. ;  segment register strategy:
  102. ;      use ds to access variables in the code segment and the device header
  103. ;      use es to access the ceh structure.
  104. ;
  105.         sti                     ; turn interrupts back on
  106.         push    bx              ; push required registers
  107.         push    cx
  108.         push    dx
  109.         push    ds
  110.         push    es
  111.  
  112.         ASSUME  ds:_TEXT, es:NOTHING    ; put cs in ds and tell assembler
  113.                                         ; ds references code, _TEXT seg
  114.         mov     dx, cs
  115.         mov     ds, dx
  116.  
  117.         mov     dx, di                          ; put error code in dx
  118.         xor     dh, dh                          ; high part of di is undef'ed
  119.         mov     bx, WORD PTR ceh_pointer+2      ; get SEGMENT of ceh struc
  120.         mov     es, bx                          ; put it in es
  121.         mov     di, WORD PTR ceh_pointer        ; get OFFSET of ceh struc
  122.         mov     WORD PTR es:[di].ecode, dx      ; save error code
  123.         mov     dl, ah                          ; move error stuff to dl
  124.         and     dl, 1                           ; 1 == write error
  125.         mov     WORD PTR es:[di].rw, dx         ; save read/write error code
  126.  
  127.         mov     dl, al                          ; put drive letter in dl
  128.         mov     WORD PTR es:[di].drive, dx      ; save drive number
  129.         test    ah, 80h                 ; was this a character or block dev
  130.         jz      drive_err               ; if fail, then block error
  131.         mov     ds, bp                  ; put SEGMENT of device header in ds
  132.         mov     dx, WORD PTR [si].dev_attr_word ; see DOS tech ref, get dev attr
  133.         test    dx, 8000h               ; was there a prob w/ FAT
  134.         jz      drive_err               ; if bit 15 == 0, drive error - FAT prob
  135.         mov     WORD PTR es:[di].dattr, 1       ; 1 == character device
  136.         mov     bx, di                  ; save OFFSET of CEH struct in bx
  137.         add     di, dname               ; load destination of char dev name
  138.         add     si, char_dev_name       ; char dev
  139.         mov     cx, 8                   ; char name is 8 bytes
  140.         rep     movsb                   ; move 8 bytes of driver name
  141.         xor     al, al                  ; zero out al
  142.         stosb                           ; store a terminating NULL
  143.         mov     di, bx                  ; get back the OFFSET of CEH struct
  144.         jmp     SHORT get_extended_error
  145.         ALIGN   2
  146. drive_err:
  147.         mov     WORD PTR es:[di].dattr, 0       ; 0 == disk drive
  148. get_extended_error:
  149.         mov     dx, cs                  ; put cs back into ds
  150.         mov     ds, dx
  151.         mov     ax, WORD PTR ds:dos_version     ; get DOS version
  152.         or      ax, ax                  ; is it 0?
  153.         jz      no_ext_avail            ; skip extended error
  154.  
  155. ;
  156. ; page 1-216, Programmer's Ref Man, 1986, function 59h pretty much wipes
  157. ; out all registers that don't return info.  function 59h is available
  158. ; for DOS >= 3.
  159. ;
  160.         push    di
  161.         push    ds
  162.         push    es
  163.         xor     bx, bx                  ; version indicator, 0 = current
  164.         mov     ah, 59h                 ; function 59h == get extended err
  165.         int     21h                     ; Standard DOS interrupt
  166.         pop     es
  167.         pop     ds
  168.         pop     di
  169.         cmp     ax, 88                          ; check for return code > 88
  170.         ja      no_ext_avail                    ; if ax <= 88, we have info
  171.         mov     WORD PTR es:[di].extended, ax   ; save ext err code
  172.         xor     ax, ax                          ; zero out ax
  173.         mov     al, bh                          ; get error class
  174.         mov     WORD PTR es:[di].class, ax      ; save error class
  175.         mov     al, bl                          ; get suggested action
  176.         mov     WORD PTR es:[di].action, ax     ; save suggested action
  177.         mov     al, ch                          ; get locus
  178.         mov     WORD PTR es:[di].locus, ax      ; save locus
  179.         jmp     SHORT prompt_user               ; now, ask user what to do
  180.         ALIGN   2
  181.  
  182. no_ext_avail:
  183.         xor     ax, ax                          ; zero out ax
  184.         mov     WORD PTR es:[di].extended, ax   ; not avail
  185.         mov     WORD PTR es:[di].class, ax      ; not avail
  186.         mov     WORD PTR es:[di].action, ax     ; not avail
  187.         mov     WORD PTR es:[di].locus, ax      ; not avail
  188.  
  189. prompt_user:
  190.         push    di                      ; save OFFSET of CEH struct
  191.         push    es                      ; save SEGMENT OF CEH struct
  192.         push    ds                      ; save code segment in ds
  193.         mov     ax, ss                  ; put stack segment in ds
  194.         mov     ds, ax                  ; C routine expects stack seg in ds
  195.         call    FAR PTR _crit_err_handler       ; return code is in ax
  196.         pop     ds                      ; get back our registers
  197.         pop     es
  198.         pop     di
  199.  
  200.         mov     bx, WORD PTR ds:dos_version     ; get the DOS version
  201.         or      bx, bx                          ; is bx == 0?
  202.         jne     retry_or_fail                   ; DOS version is >= 3
  203.         cmp     ax, 3                           ; did user try fail?
  204.         jne     retry_or_fail                   ; cannot fail with DOS < 3
  205.         mov     ax, 0                           ; change it to Ignore
  206.         ALIGN   2
  207.  
  208. retry_or_fail:
  209.         mov     dx, -1                          ; if we fail, store a -1
  210.         cmp     ax, 1                           ; did user do a retry?
  211.         jne     end_int_24                      ; if retry, change error code
  212.         xor     dx, dx                          ;   reset error flag on retry
  213.  
  214. end_int_24:
  215.         mov     WORD PTR es:[di].flag, dx       ; save ceh flag
  216.         pop     es
  217.         pop     ds
  218.         pop     dx
  219.         pop     cx
  220.         pop     bx              ; pop registers
  221.         iret                    ; return from interrupt
  222.  
  223. ; ***********************************************************************
  224. ; prototype for _install_ceh in the C header file, tdefunc.h, is
  225. ;
  226. ;               void far install_ceh( void far * )
  227. ;
  228. ; The formal parameters are available on the stack.  Use bp register to
  229. ; access them.
  230. ;
  231. ; ***********************************************************************
  232.  
  233. initialize:
  234.         push    bp              ; setup bp to access formal parameter
  235.         mov     bp, sp
  236.  
  237.         push    ds              ; save ds
  238.  
  239.         ASSUME  ds:_TEXT        ; tell assembler ds references code, _TEXT seg
  240.         mov     ax, cs
  241.         mov     ds, ax          ; put cs in ds - required by function 25h, below
  242.  
  243.         mov     ah, 30h         ; function 30h == get DOS version
  244.         int     21h             ; DOS interrupt
  245.         xor     bx, bx          ; start out with zero for DOS version
  246.         cmp     al, 3           ; compare major version
  247.         jl      store_dos       ; if less than version 3, store 0
  248.         mov     bx, 3           ; else store 3 for DOS >= 3
  249. store_dos:
  250.         mov     WORD PTR dos_version, bx        ; save DOS info for my int 24
  251.  
  252.         mov     ax, WORD PTR [bp+6]             ; load OFFSET of void FAR *
  253.         mov     WORD PTR ceh_pointer, ax        ; save OFFSET of void FAR *
  254.         mov     ax, WORD PTR [bp+8]             ; load SEGMENT of void FAR *
  255.         mov     WORD PTR ceh_pointer+2, ax      ; save SEGMENT of void FAR *
  256.  
  257.         mov     dx, OFFSET start        ; get new offset of int 24
  258.                                         ; we have already set ds above
  259.         mov     ax, 2524h               ; use function 25 so int 24 points
  260.         int     21h                     ;  to my critical error routine
  261.  
  262.         pop     ds              ; clean up
  263.         pop     bp
  264.         retf
  265. _install_ceh            endp
  266. _TEXT   ends
  267.         end
  268.